package com.crazymakercircle.mutithread.basic.create;

import com.crazymakercircle.mutithread.basic.create3.CreateThreadPoolDemo;
import com.crazymakercircle.util.ThreadUtil;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.ThreadPoolExecutor;

import static com.crazymakercircle.util.ThreadUtil.MIXED_THREAD_AMOUNT;
import static com.crazymakercircle.util.ThreadUtil.getCurThreadName;
import static com.crazymakercircle.util.ThreadUtil.sleepMilliSeconds;
import static com.crazymakercircle.util.ThreadUtil.sleepSeconds;

/**
 * Executors里面提供了四个创建线程的方法，缺点如下：
 * 1、对于阻塞队列无限的，可能会造成OOM
 * 2、对于创建线程无限的也可能造成OOM
 */
@Slf4j
public class ThreadPoolDemo {
    public static final int MAX_TURN = 5;
    static int threadNo = 1;

    @Test
    public void testIoIntenseTargetThreadPool() {
        ThreadPoolExecutor pool = ThreadUtil.getIoIntenseTargetThreadPool();
        for (int i = 0; i < 2; i++) {
            pool.submit(new Runnable() {
                @Override
                public void run() {
                    for (int j = 1; j < MAX_TURN; j++) {
                        log.info(getCurThreadName() + ", 轮次：" + j);
                    }
                    log.info(getCurThreadName() + " 运行结束.");
                }
            });
        }
        ThreadUtil.sleepMilliSeconds(10);
    }

    @Test
    public void testCpuIntenseTargetThreadPool() {
        ThreadPoolExecutor pool = ThreadUtil.getCpuIntenseTargetThreadPool();
        for (int i = 0; i < 2; i++) {
            pool.submit(new Runnable() {
                @Override
                public void run() {
                    for (int j = 1; j < MAX_TURN; j++) {
                        log.info(getCurThreadName() + ", 轮次：" + j);
                    }
                    log.info(getCurThreadName() + " 运行结束.");
                }
            });
        }
        ThreadUtil.sleepMilliSeconds(10);
    }

    @Test
    public void testMixedThreadPool() {
        System.getProperties().setProperty(MIXED_THREAD_AMOUNT, "80");
        // 获取自定义的混合线程池
        ExecutorService pool = ThreadUtil.getMixedTargetThreadPool();
        for (int i = 0; i < 1000; i++) {
            try {
                sleepMilliSeconds(10);
                pool.submit(new CreateThreadPoolDemo.TargetTask());

            } catch (RejectedExecutionException e) {
                log.error("error:{}", e.getMessage());
            }
        }
        //等待10s
        sleepSeconds(10);
        log.info("关闭线程池");
    }

    static class RunTarget implements Runnable {  //① 实现Runnable接口
        public void run() { //② 在这些写业务逻辑
            for (int j = 1; j < MAX_TURN; j++) {
                log.info(getCurThreadName() + ", 轮次：" + j);
            }
            log.info(getCurThreadName() + " 运行结束.");
        }
    }

}